#import <appkit/Window.h>
#import <appkit/TextField.h>
#import <appkit/OpenPanel.h>
#import <appkit/ScrollView.h>
#import <appkit/Text.h>

#import <objc/List.h>
#import <objc/objc.h>

#import <stdio.h>
#import <string.h>
#import <stdlib.h>

#import "DynamicApplication.h"
#import "Controller.h"
#import "MatrixScrollView.h"

@implementation Controller

BOOL getFullFileName( fullpath )
char *fullpath;
{
    const char 		*types[2] = { "o", NULL };
    const char *const 	*filename;
    id			openReq;
    
    openReq = [OpenPanel new];
    if([openReq runModalForTypes:types] && (filename = [openReq filenames]))
    {
        strcpy( fullpath, [openReq directory] );
	strcat( fullpath, "/" );
	strcat( fullpath, filename[0] );
	
        return YES;
    }
    else
        return NO;
}

- appDidInit:sender
{    
    [classesNumberField setIntValue:[NXApp classesNum]];
    [loadedClasses setTarget:self action:@selector(classClick:)];  
    return self;
}

- loadAClass:sender
{
    char temp[1024];

    if( getFullFileName( &temp ) )
    {
    	[NXApp loadClass:temp];
    
	if( [NXApp classLoaded] )
	{
	    [loadedClasses insertName:[NXApp lastClassName] alphaOrder:NO select:NO];
	    [classesNumberField setIntValue:[NXApp classesNum]];
	    if([NXApp classesNum] == 1 )
		[self classClick:self];
	}
    }
    
    return self;
}

- classClick:sender
{
    id	tempObject;
    
    tempObject = [[NXApp classWithName:[loadedClasses selectedName]] alloc];
    [self methodListForObject:tempObject];
    [tempObject free];
    
    return self;
}

- (int)printf:(id)scrollView string:(const char *)format, ...
{
    int result, length = [[scrollView docView] textLength];
    char buffer[1024];
    va_list ap;
    
    va_start( ap, format );
    result = vsprintf( buffer, format, ap );
    va_end( ap );
    
    [[[scrollView docView] setSel:length :length] replaceSel:buffer];
    
    return result;
}

- methodListForObject:(Controller *)anObject
{
    struct objc_class 		*c;
    struct objc_method_list 	*m;
    struct objc_ivar_list	*v;
    char			*n;
    int				i;
    
    c = anObject->isa;
    v = c->ivars;
    m = c->methods;
    
    [[instanceVars docView] setText:""];
    [[instanceMethods docView] setText:""];
    [[instanceVars window] disableFlushWindow];

    if( v )
    	for( i = v->ivar_count-1 ; i >= 0 ; i-- )
	    [self printf:instanceVars string:"%s\n", v->ivar_list[i].ivar_name];

    if( m )
    	for( i = m->method_count-1 ; i >= 0 ; i-- )
    	{
            n = sel_getName( m->method_list[i].method_name );
	    [self printf:instanceMethods string:"- %s\n", n];
    	}

    [[instanceVars window] reenableFlushWindow];
    [[instanceVars window] flushWindow];
    [instanceVars display];
    [instanceMethods display];
    
    return self;
}

@end
